using System.IO;
using Framework.Core.Recorder;
using Xunit;

namespace Framework.Tests.Core.Recorder.AcceptanceTests
{
    extern alias castlecore;

    public class RecorderAndReplayerTest
    {
        [Fact]
        public void Should_record_and_replay_multiple_times()
        {
            var recorder = new HardMock().BuildRecorderOver<_MUODate>(new MUODate());

            var target = new Target(recorder);
            Assert.Equal("a", target.JustDoIt());

            using (var stream = new MemoryStream())
            {
                recorder.Snapshot(stream);

                var replayer = new HardMock().BuildMockFrom<_MUODate>(stream);

                var target2 = new Target(replayer);

                for (var i = 0; i < 10; i++)
                {
                    Assert.Equal("a", target2.JustDoIt());
                }
            }
        }

        [Fact]
        public void Should_throw_not_record_exception_when_call_is_not_in_repository()
        {
            var hardMock = new HardMock();
            var recorder = hardMock.BuildRecorderOver<_MUODate>(new MUODate());

            recorder.Do("a", "b");

            using (var stream = new MemoryStream())
            {
                recorder.Snapshot(stream);

                var replayer = hardMock.BuildMockFrom<_MUODate>(stream);

                Assert.Throws<NotRecordedException>(() => replayer.Do("b", "a"));
            }
        }

        [Fact]
        public void Should_replay_for_by_ref_args_when_args_value_changed()
        {
            var recorder = new HardMock().BuildRecorderOver<_MUODate>(new MUODate());

            var b = "pouet";
            recorder.Control(ref b);
            Assert.Equal("toto", b);

            using (var stream = new MemoryStream())
            {
                recorder.Snapshot(stream);

                var replayer = new HardMock().BuildMockFrom<_MUODate>(stream);
                var p = "pouet";
                replayer.Control(ref p);
                Assert.Equal("toto", p);
            }
        }

    }
}